package top.haijunit.work.modules.core;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;
import top.haijunit.work.core.doamin.ExceptionServer;
import top.haijunit.work.core.doamin.PageQuery;
import top.haijunit.work.core.doamin.ResultPage;

import java.util.Collection;
import java.util.List;
import java.util.Objects;

/**
 * 【说明类功能】
 *
 * @author zhanghaijun
 * @since 2024-08-27
 */
@Slf4j
public abstract class BaseService<M extends BaseMapper<T>, T extends BaseEntity, D> extends ServiceImpl<M, T> {

    /**
     * 类型转换
     */
    public abstract List<D> convert(List<T> ts);

    public abstract D convert(T ts);

    public abstract T convert(D dto);

    /**
     * 获取查询条件
     */
    public Wrapper<T> queryConditional(D dto) {
        LambdaQueryWrapper<T> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(T::getCreateTime);
        return queryWrapper;
    }

    /**
     * 校验数据
     */
    public void checkChange(D dto) {
    }

    /**
     * 获取数据分页
     */
    public ResultPage<D> selectPageList(D dto, PageQuery pageQuery) {
        Page<T> entityPage = this.baseMapper.selectPage(pageQuery.build(), queryConditional(dto));
        return ResultPage.build(entityPage, this::convert);
    }

    /**
     * 获取数据列表
     */
    public Collection<D> selectList(D dto) {
        List<T> entityList = this.baseMapper.selectList(queryConditional(dto));
        return convert(entityList);
    }

    /**
     * 获取数据详情
     */
    public D selectDetail(Long code) {
        if (Objects.isNull(code)) {
            throw new ExceptionServer("数据不存在");
        }
        LambdaQueryWrapper<T> query = new LambdaQueryWrapper<>();
        query.eq(T::getUniqCode, code);
        List<T> entityList = this.baseMapper.selectList(query);
        if (CollUtil.isEmpty(entityList)) {
            throw new ExceptionServer("数据不存在");
        }
        if (entityList.size() > 1) {
            log.error("数据库数据异常，存在重复的异常数据: {} 重复", code);
        }
        return convert(CollUtil.getFirst(entityList));
    }

    /**
     * 添加数据
     */
    public Long insert(D dto) {
        checkChange(dto);
        T entity = this.convert(dto);
        this.baseMapper.insert(entity);
        return entity.getUniqCode();
    }

    /**
     * 修改数据
     */
    public Long modify(D dto) {
        checkChange(dto);
        T entity = this.convert(dto);
        Assert.notNull(entity.getUniqCode(), "修改的数据不存在");
        LambdaQueryWrapper<T> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(T::getUniqCode, entity.getUniqCode());
        this.baseMapper.update(entity, wrapper);
        return entity.getUniqCode();
    }

    /**
     * 删除数据
     */
    public Long delete(Long code) {
        LambdaQueryWrapper<T> query = new LambdaQueryWrapper<>();
        query.eq(T::getUniqCode, code);
        this.baseMapper.delete(query);
        return code;
    }
}
